package library

///
// 缓冲库
///

// BufferByte 缓存数据
type BufferByte struct {
	Value  interface{} // 数据
	Employ bool        // 使用
}

// Buffer 缓存类
type Buffer struct {
	Number int
	TimeID int64
	Queue  map[int]*BufferByte
	// 锁
	lock chan bool
}

// Init 初始化
func (B *Buffer) Init(Number int) {
	B.lock = make(chan bool, 1)
	B.Queue = make(map[int]*BufferByte, 0)
	B.Number = Number
	// 超时解锁
	B.TimeID = Cycle.ADD(1000, func() {
		var N int
		for _, b := range B.Queue {
			if !b.Employ {
				N++
			}
		}
		if N == B.Number {
			Cycle.SetStop(B.TimeID, true) // 全部已解锁停止释放
			<-B.lock                      // 解锁
		}
	})
	Cycle.SetStop(B.TimeID, true) // 停止
}

// Get 获得缓冲
func (B *Buffer) Get() *BufferByte {
	// 锁主
	B.lock <- false
	// 返回空闲数据
	for _, b := range B.Queue {
		if !b.Employ {
			b.Employ = true
			<-B.lock
			return b
		}
	}
	// 添加新数据
	n := len(B.Queue) + 1
	B.Queue[n] = &BufferByte{Employ: true}
	// 判断是否已满
	if n == B.Number {
		// 启动等待
		Cycle.SetStop(B.TimeID, false) // 启动
		// 不进行解锁会将后面的全部锁上
		return B.Queue[n]
	}
	<-B.lock
	return B.Queue[n]
}
